﻿package core.image
{
    import __AS3__.vec.*;
    import flash.display.*;
    import flash.filters.*;
    import flash.geom.*;

    public class ColorMatrix extends Object
    {
        public var matrix:Array;
        private var preHue:ColorMatrix;
        private var postHue:ColorMatrix;
        private var hueInitialized:Boolean;
        public static const COLOR_DEFICIENCY_TYPES:Array = ["Protanopia", "Protanomaly", "Deuteranopia", "Deuteranomaly", "Tritanopia", "Tritanomaly", "Achromatopsia", "Achromatomaly"];
        private static const LUMA_R:Number = 0.212671;
        private static const LUMA_G:Number = 0.71516;
        private static const LUMA_B:Number = 0.072169;
        private static const LUMA_R2:Number = 0.3086;
        private static const LUMA_G2:Number = 0.6094;
        private static const LUMA_B2:Number = 0.082;
        private static const ONETHIRD:Number = 0.333333;
        private static const IDENTITY:Array = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
        private static const RAD:Number = 0.0174533;

        public function ColorMatrix(param1:Object = null)
        {
            if (param1 is ColorMatrix)
            {
                this.matrix = param1.matrix.concat();
            }
            else if (param1 is Array)
            {
                this.matrix = param1.concat();
            }
            else
            {
                this.reset();
            }
            return;
        }// end function

        public function reset() : void
        {
            this.matrix = IDENTITY.concat();
            return;
        }// end function

        public function clone() : ColorMatrix
        {
            return new ColorMatrix(this.matrix);
        }// end function

        public function Invert() : void
        {
            this.concat([-1, 0, 0, 0, 255, 0, -1, 0, 0, 255, 0, 0, -1, 0, 255, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function AdjustSaturation(Math:Number = 1) : void
        {
            var _loc_2:Number = NaN;
            var _loc_3:Number = NaN;
            var _loc_4:Number = NaN;
            var _loc_5:Number = NaN;
            _loc_2 = 1 - Math;
            _loc_3 = _loc_2 * LUMA_R;
            _loc_4 = _loc_2 * LUMA_G;
            _loc_5 = _loc_2 * LUMA_B;
            this.concat([_loc_3 + Math, _loc_4, _loc_5, 0, 0, _loc_3, _loc_4 + Math, _loc_5, 0, 0, _loc_3, _loc_4, _loc_5 + Math, 0, 0, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function AdjustContrast(Math:Number = 0, Math:Number = NaN, Math:Number = NaN) : void
        {
            if (isNaN(Math))
            {
                Math = Math;
            }
            if (isNaN(Math))
            {
                Math = Math;
            }
            Math = Math + 1;
            Math = Math + 1;
            Math = Math + 1;
            this.concat([Math, 0, 0, 0, 128 * (1 - Math), 0, Math, 0, 0, 128 * (1 - Math), 0, 0, Math, 0, 128 * (1 - Math), 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function AdjustBrightness(Math:Number = 0, Math:Number = NaN, Math:Number = NaN) : void
        {
            if (isNaN(Math))
            {
                Math = Math;
            }
            if (isNaN(Math))
            {
                Math = Math;
            }
            this.concat([1, 0, 0, 0, Math, 0, 1, 0, 0, Math, 0, 0, 1, 0, Math, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function toGreyscale(Math:Number = 0.212671, Math:Number = 0.71516, Math:Number = 0.072169) : void
        {
            this.concat([Math, Math, Math, 0, 0, Math, Math, Math, 0, 0, Math, Math, Math, 0, 0, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function AdjustHue(Math:Number = 0) : void
        {
            Math = Math * RAD;
            var _loc_2:* = Math.cos(Math);
            var _loc_3:* = Math.sin(Math);
            this.concat([LUMA_R + _loc_2 * (1 - LUMA_R) + _loc_3 * (-LUMA_R), LUMA_G + _loc_2 * (-LUMA_G) + _loc_3 * (-LUMA_G), LUMA_B + _loc_2 * (-LUMA_B) + _loc_3 * (1 - LUMA_B), 0, 0, LUMA_R + _loc_2 * (-LUMA_R) + _loc_3 * 0.143, LUMA_G + _loc_2 * (1 - LUMA_G) + _loc_3 * 0.14, LUMA_B + _loc_2 * (-LUMA_B) + _loc_3 * -0.283, 0, 0, LUMA_R + _loc_2 * (-LUMA_R) + _loc_3 * (-(1 - LUMA_R)), LUMA_G + _loc_2 * (-LUMA_G) + _loc_3 * LUMA_G, LUMA_B + _loc_2 * (1 - LUMA_B) + _loc_3 * LUMA_B, 0, 0, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function rotateHue(Math:Number = 0) : void
        {
            this.initHue();
            this.concat(this.preHue.matrix);
            this.rotateBlue(Math);
            this.concat(this.postHue.matrix);
            return;
        }// end function

        public function luminance2Alpha() : void
        {
            this.concat([0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, LUMA_R, LUMA_G, LUMA_B, 0, 0]);
            return;
        }// end function

        public function adjustAlphaContrast(Math:Number = 0) : void
        {
            Math = Math + 1;
            this.concat([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, Math, 128 * (1 - Math)]);
            return;
        }// end function

        public function Colorize(Math:int, Math:Number = 1) : void
        {
            var _loc_3:Number = NaN;
            var _loc_4:Number = NaN;
            var _loc_5:Number = NaN;
            var _loc_6:Number = NaN;
            _loc_3 = (Math >> 16 & 255) / 255;
            _loc_4 = (Math >> 8 & 255) / 255;
            _loc_5 = (Math & 255) / 255;
            _loc_6 = 1 - Math;
            this.concat([_loc_6 + Math * _loc_3 * LUMA_R, Math * _loc_3 * LUMA_G, Math * _loc_3 * LUMA_B, 0, 0, Math * _loc_4 * LUMA_R, _loc_6 + Math * _loc_4 * LUMA_G, Math * _loc_4 * LUMA_B, 0, 0, Math * _loc_5 * LUMA_R, Math * _loc_5 * LUMA_G, _loc_6 + Math * _loc_5 * LUMA_B, 0, 0, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function setChannels(Math:int = 1, Math:int = 2, Math:int = 4, Math:int = 8) : void
        {
            var _loc_5:* = (((Math & 1) == 1 ? (1) : (0 + ((Math & 2) == 2) ? (1) : (0))) + ((Math & 4) == 4) ? (1) : (0)) + ((Math & 8) == 8) ? (1) : (0);
            if (_loc_5 > 0)
            {
                _loc_5 = 1 / _loc_5;
            }
            var _loc_6:* = (((Math & 1) == 1 ? (1) : (0 + ((Math & 2) == 2) ? (1) : (0))) + ((Math & 4) == 4) ? (1) : (0)) + ((Math & 8) == 8) ? (1) : (0);
            if (_loc_6 > 0)
            {
                _loc_6 = 1 / _loc_6;
            }
            var _loc_7:* = (((Math & 1) == 1 ? (1) : (0 + ((Math & 2) == 2) ? (1) : (0))) + ((Math & 4) == 4) ? (1) : (0)) + ((Math & 8) == 8) ? (1) : (0);
            if (_loc_7 > 0)
            {
                _loc_7 = 1 / _loc_7;
            }
            var _loc_8:* = (((Math & 1) == 1 ? (1) : (0 + ((Math & 2) == 2) ? (1) : (0))) + ((Math & 4) == 4) ? (1) : (0)) + ((Math & 8) == 8) ? (1) : (0);
            if (_loc_8 > 0)
            {
                _loc_8 = 1 / _loc_8;
            }
            this.concat([(Math & 1) == 1 ? (_loc_5) : (0), (Math & 2) == 2 ? (_loc_5) : (0), (Math & 4) == 4 ? (_loc_5) : (0), (Math & 8) == 8 ? (_loc_5) : (0), 0, (Math & 1) == 1 ? (_loc_6) : (0), (Math & 2) == 2 ? (_loc_6) : (0), (Math & 4) == 4 ? (_loc_6) : (0), (Math & 8) == 8 ? (_loc_6) : (0), 0, (Math & 1) == 1 ? (_loc_7) : (0), (Math & 2) == 2 ? (_loc_7) : (0), (Math & 4) == 4 ? (_loc_7) : (0), (Math & 8) == 8 ? (_loc_7) : (0), 0, (Math & 1) == 1 ? (_loc_8) : (0), (Math & 2) == 2 ? (_loc_8) : (0), (Math & 4) == 4 ? (_loc_8) : (0), (Math & 8) == 8 ? (_loc_8) : (0), 0]);
            return;
        }// end function

        public function blend(Math:ColorMatrix, Math:Number) : void
        {
            var _loc_3:* = 1 - Math;
            var _loc_4:int = 0;
            while (_loc_4 < 20)
            {
                
                this.matrix[_loc_4] = _loc_3 * Number(this.matrix[_loc_4]) + Math * Number(Math.matrix[_loc_4]);
                _loc_4++;
            }
            return;
        }// end function

        public function average(Math:Number = 0.333333, Math:Number = 0.333333, Math:Number = 0.333333) : void
        {
            this.concat([Math, Math, Math, 0, 0, Math, Math, Math, 0, 0, Math, Math, Math, 0, 0, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function Threshold(Math:Number, Math:Number = 256) : void
        {
            this.concat([LUMA_R * Math, LUMA_G * Math, LUMA_B * Math, 0, (-(Math - 1)) * Math, LUMA_R * Math, LUMA_G * Math, LUMA_B * Math, 0, (-(Math - 1)) * Math, LUMA_R * Math, LUMA_G * Math, LUMA_B * Math, 0, (-(Math - 1)) * Math, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function AlphaThreshold(Math:Number, Math:Number = 256) : void
        {
            this.concat([Math, 0, 0, 0, (-(Math - 1)) * Math, 0, Math, 0, 0, (-(Math - 1)) * Math, 0, 0, Math, 0, (-(Math - 1)) * Math, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function Desaturate() : void
        {
            this.concat([LUMA_R, LUMA_G, LUMA_B, 0, 0, LUMA_R, LUMA_G, LUMA_B, 0, 0, LUMA_R, LUMA_G, LUMA_B, 0, 0, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function setMultiplicators(Math:Number = 1, Math:Number = 1, Math:Number = 1, Math:Number = 1) : void
        {
            var _loc_5:* = new Array(Math, 0, 0, 0, 0, 0, Math, 0, 0, 0, 0, 0, Math, 0, 0, 0, 0, 0, Math, 0);
            this.concat(_loc_5);
            return;
        }// end function

        public function clearChannels(Math:Boolean = false, Math:Boolean = false, Math:Boolean = false, Math:Boolean = false) : void
        {
            if (Math)
            {
                var _loc_5:int = 0;
                this.matrix[4] = 0;
                var _loc_5:* = _loc_5;
                this.matrix[3] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[2] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[1] = _loc_5;
                this.matrix[0] = _loc_5;
            }
            if (Math)
            {
                var _loc_5:int = 0;
                this.matrix[9] = 0;
                var _loc_5:* = _loc_5;
                this.matrix[8] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[7] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[6] = _loc_5;
                this.matrix[5] = _loc_5;
            }
            if (Math)
            {
                var _loc_5:int = 0;
                this.matrix[14] = 0;
                var _loc_5:* = _loc_5;
                this.matrix[13] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[12] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[11] = _loc_5;
                this.matrix[10] = _loc_5;
            }
            if (Math)
            {
                var _loc_5:int = 0;
                this.matrix[19] = 0;
                var _loc_5:* = _loc_5;
                this.matrix[18] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[17] = _loc_5;
                var _loc_5:* = _loc_5;
                this.matrix[16] = _loc_5;
                this.matrix[15] = _loc_5;
            }
            return;
        }// end function

        public function thresholdAlpha(Math:Number = 0.5, Math:Number = 256) : void
        {
            this.concat([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, Math, (-Math) * Math]);
            return;
        }// end function

        public function averageRGB2Alpha() : void
        {
            this.concat([0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, ONETHIRD, ONETHIRD, ONETHIRD, 0, 0]);
            return;
        }// end function

        public function InvertAlpha() : void
        {
            this.concat([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 255]);
            return;
        }// end function

        public function rgb2Alpha(Math:Number = 0.333333, Math:Number = 0.333333, Math:Number = 0.333333) : void
        {
            this.concat([0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, Math, Math, Math, 0, 0]);
            return;
        }// end function

        public function setAlpha(Math:Number = 1) : void
        {
            this.concat([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, Math, 0]);
            return;
        }// end function

        public function get filter() : ColorMatrixFilter
        {
            return new ColorMatrixFilter(this.matrix);
        }// end function

        public function applyFilter(Math:BitmapData) : void
        {
            Math.applyFilter(Math, Math.rect, new Point(), this.filter);
            return;
        }// end function

        public function concat(Math:Array) : void
        {
            var _loc_4:int = 0;
            var _loc_5:int = 0;
            var _loc_2:Array = [];
            var _loc_3:int = 0;
            _loc_5 = 0;
            while (_loc_5 < 4)
            {
                
                _loc_4 = 0;
                while (_loc_4 < 5)
                {
                    
                    _loc_2[int(_loc_3 + _loc_4)] = Number(Math[_loc_3]) * Number(this.matrix[_loc_4]) + Number(Math[int((_loc_3 + 1))]) * Number(this.matrix[int(_loc_4 + 5)]) + Number(Math[int(_loc_3 + 2)]) * Number(this.matrix[int(_loc_4 + 10)]) + Number(Math[int(_loc_3 + 3)]) * Number(this.matrix[int(_loc_4 + 15)]) + (_loc_4 == 4 ? (Number(Math[int(_loc_3 + 4)])) : (0));
                    _loc_4++;
                }
                _loc_3 = _loc_3 + 5;
                _loc_5++;
            }
            this.matrix = _loc_2;
            return;
        }// end function

        public function rotateRed(Math:Number = 0) : void
        {
            this.rotateColor(Math, 2, 1);
            return;
        }// end function

        public function rotateGreen(Math:Number = 0) : void
        {
            this.rotateColor(Math, 0, 2);
            return;
        }// end function

        public function rotateBlue(Math:Number = 0) : void
        {
            this.rotateColor(Math, 1, 0);
            return;
        }// end function

        public function normalize() : void
        {
            var _loc_2:Number = NaN;
            var _loc_3:int = 0;
            var _loc_1:int = 0;
            while (_loc_1 < 4)
            {
                
                _loc_2 = 0;
                _loc_3 = 0;
                while (_loc_3 < 4)
                {
                    
                    _loc_2 = _loc_2 + this.matrix[_loc_1 * 5 + _loc_3] * this.matrix[_loc_1 * 5 + _loc_3];
                    _loc_3++;
                }
                _loc_2 = 1 / Math.sqrt(_loc_2);
                if (_loc_2 != 1)
                {
                    _loc_3 = 0;
                    while (_loc_3 < 4)
                    {
                        
                        this.matrix[_loc_1 * 5 + _loc_3] = this.matrix[_loc_1 * 5 + _loc_3] * _loc_2;
                        _loc_3++;
                    }
                }
                _loc_1++;
            }
            return;
        }// end function

        public function fitRange() : void
        {
            var _loc_2:Number = NaN;
            var _loc_3:Number = NaN;
            var _loc_4:int = 0;
            var _loc_5:Number = NaN;
            var _loc_6:Number = NaN;
            var _loc_7:Number = NaN;
            var _loc_8:Number = NaN;
            var _loc_1:int = 0;
            while (_loc_1 < 4)
            {
                
                _loc_2 = 0;
                _loc_3 = 0;
                _loc_4 = 0;
                while (_loc_4 < 4)
                {
                    
                    if (this.matrix[int(_loc_1 * 5 + _loc_4)] < 0)
                    {
                        _loc_2 = _loc_2 + this.matrix[int(_loc_1 * 5 + _loc_4)];
                    }
                    else
                    {
                        _loc_3 = _loc_3 + this.matrix[int(_loc_1 * 5 + _loc_4)];
                    }
                    _loc_4++;
                }
                _loc_5 = _loc_3 * 255 - _loc_2 * 255;
                _loc_6 = 255 / _loc_5;
                if (_loc_6 != 1)
                {
                    _loc_4 = 0;
                    while (_loc_4 < 4)
                    {
                        
                        this.matrix[int(_loc_1 * 5 + _loc_4)] = this.matrix[int(_loc_1 * 5 + _loc_4)] * _loc_6;
                        _loc_4++;
                    }
                }
                _loc_2 = 0;
                _loc_3 = 0;
                _loc_4 = 0;
                while (_loc_4 < 4)
                {
                    
                    if (this.matrix[int(_loc_1 * 5 + _loc_4)] < 0)
                    {
                        _loc_2 = _loc_2 + this.matrix[int(_loc_1 * 5 + _loc_4)];
                    }
                    else
                    {
                        _loc_3 = _loc_3 + this.matrix[int(_loc_1 * 5 + _loc_4)];
                    }
                    _loc_4++;
                }
                _loc_7 = _loc_2 * 255;
                _loc_8 = _loc_3 * 255;
                this.matrix[int(_loc_1 * 5 + 4)] = -(_loc_7 + (_loc_8 - _loc_7) * 0.5 - 127.5);
                _loc_1++;
            }
            return;
        }// end function

        public function shearRed(Math:Number, Math:Number) : void
        {
            this.shearColor(0, 1, Math, 2, Math);
            return;
        }// end function

        public function shearGreen(Math:Number, Math:Number) : void
        {
            this.shearColor(1, 0, Math, 2, Math);
            return;
        }// end function

        public function shearBlue(Math:Number, Math:Number) : void
        {
            this.shearColor(2, 0, Math, 1, Math);
            return;
        }// end function

        public function applyColorDeficiency(Math:String) : void
        {
            switch(Math)
            {
                case "Protanopia":
                {
                    this.concat([0.567, 0.433, 0, 0, 0, 0.558, 0.442, 0, 0, 0, 0, 0.242, 0.758, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                case "Protanomaly":
                {
                    this.concat([0.817, 0.183, 0, 0, 0, 0.333, 0.667, 0, 0, 0, 0, 0.125, 0.875, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                case "Deuteranopia":
                {
                    this.concat([0.625, 0.375, 0, 0, 0, 0.7, 0.3, 0, 0, 0, 0, 0.3, 0.7, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                case "Deuteranomaly":
                {
                    this.concat([0.8, 0.2, 0, 0, 0, 0.258, 0.742, 0, 0, 0, 0, 0.142, 0.858, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                case "Tritanopia":
                {
                    this.concat([0.95, 0.05, 0, 0, 0, 0, 0.433, 0.567, 0, 0, 0, 0.475, 0.525, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                case "Tritanomaly":
                {
                    this.concat([0.967, 0.033, 0, 0, 0, 0, 0.733, 0.267, 0, 0, 0, 0.183, 0.817, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                case "Achromatopsia":
                {
                    this.concat([0.299, 0.587, 0.114, 0, 0, 0.299, 0.587, 0.114, 0, 0, 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                case "Achromatomaly":
                {
                    this.concat([0.618, 0.32, 0.062, 0, 0, 0.163, 0.775, 0.062, 0, 0, 0.163, 0.32, 0.516, 0, 0, 0, 0, 0, 1, 0]);
                    break;
                }
                default:
                {
                    break;
                }
            }
            return;
        }// end function

        public function RGB2YUV() : void
        {
            this.concat([0.299, 0.587, 0.114, 0, 0, -0.16874, -0.33126, 0.5, 0, 128, 0.5, -0.41869, -0.08131, 0, 128, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function YUV2RGB() : void
        {
            this.concat([1, -7.15478e-006, 1.402, 0, -179.455, 1, -0.344133, -0.714138, 0, 135.459, 1, 1.772, 1.54257e-005, 0, -226.818, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function RGB2YIQ() : void
        {
            this.concat([0.299, 0.587, 0.114, 0, 0, 0.595716, -0.274453, -0.321263, 0, 128, 0.211456, -0.522591, -0.311135, 0, 128, 0, 0, 0, 1, 0]);
            return;
        }// end function

        public function autoDesaturate(Math:BitmapData, Math:Boolean = false, Math:Boolean = false) : void
        {
            var _loc_8:Number = NaN;
            var _loc_9:Number = NaN;
            var _loc_14:Number = NaN;
            var _loc_4:* = Math.histogram(Math.rect);
            var _loc_5:Number = 0;
            var _loc_6:Number = 0;
            var _loc_7:Number = 0;
            var _loc_10:Boolean = false;
            var _loc_11:int = 0;
            while (_loc_11 < 256)
            {
                
                _loc_5 = _loc_5 + _loc_4[0][_loc_11] * _loc_11;
                _loc_6 = _loc_6 + _loc_4[1][_loc_11] * _loc_11;
                _loc_7 = _loc_7 + _loc_4[2][_loc_11] * _loc_11;
                if (Math)
                {
                    if (_loc_4[0][_loc_11] != 0 || _loc_4[1][_loc_11] != 0 || _loc_4[2][_loc_11] != 0)
                    {
                        _loc_9 = _loc_11;
                        if (!_loc_10)
                        {
                            _loc_8 = _loc_11;
                            _loc_10 = true;
                        }
                    }
                }
                _loc_11++;
            }
            var _loc_12:* = _loc_5 + _loc_6 + _loc_7;
            if (_loc_12 == 0)
            {
                _loc_12 = 3;
                var _loc_15:int = 3;
                _loc_7 = 3;
                var _loc_15:* = _loc_15;
                _loc_6 = _loc_15;
                _loc_5 = _loc_15;
            }
            _loc_5 = _loc_5 / _loc_12;
            _loc_6 = _loc_6 / _loc_12;
            _loc_7 = _loc_7 / _loc_12;
            var _loc_13:Number = 0;
            if (Math && _loc_9 - _loc_8 < 255)
            {
                _loc_14 = 256 / (_loc_9 - _loc_8 + 1);
                _loc_5 = _loc_5 * _loc_14;
                _loc_6 = _loc_6 * _loc_14;
                _loc_7 = _loc_7 * _loc_14;
                _loc_13 = -_loc_8;
            }
            _loc_14 = 1 / Math.sqrt(_loc_5 * _loc_5 + _loc_6 * _loc_6 + _loc_7 * _loc_7);
            _loc_5 = _loc_5 * _loc_14;
            _loc_6 = _loc_6 * _loc_14;
            _loc_7 = _loc_7 * _loc_14;
            if (!Math)
            {
                this.concat([_loc_5, _loc_6, _loc_7, 0, _loc_13, _loc_5, _loc_6, _loc_7, 0, _loc_13, _loc_5, _loc_6, _loc_7, 0, _loc_13, 0, 0, 0, 1, 0]);
            }
            else
            {
                this.concat([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _loc_5, _loc_6, _loc_7, 0, _loc_13, 0, 0, 0, 1, 0]);
            }
            return;
        }// end function

        public function invertMatrix() : Boolean
        {
            var _loc_1:* = new Matrix3D(this.Vector.<Number>([this.matrix[0], this.matrix[1], this.matrix[2], this.matrix[3], this.matrix[5], this.matrix[6], this.matrix[7], this.matrix[8], this.matrix[10], this.matrix[11], this.matrix[12], this.matrix[13], this.matrix[15], this.matrix[16], this.matrix[17], this.matrix[18]]));
            var _loc_2:* = _loc_1.invert();
            if (!_loc_2)
            {
                return false;
            }
            this.matrix[0] = _loc_1.rawData[0];
            this.matrix[1] = _loc_1.rawData[1];
            this.matrix[2] = _loc_1.rawData[2];
            this.matrix[3] = _loc_1.rawData[3];
            var _loc_3:* = -(_loc_1.rawData[0] * this.matrix[4] + _loc_1.rawData[1] * this.matrix[9] + _loc_1.rawData[2] * this.matrix[14] + _loc_1.rawData[3] * this.matrix[15]);
            this.matrix[5] = _loc_1.rawData[4];
            this.matrix[6] = _loc_1.rawData[5];
            this.matrix[7] = _loc_1.rawData[6];
            this.matrix[8] = _loc_1.rawData[7];
            var _loc_4:* = -(_loc_1.rawData[4] * this.matrix[4] + _loc_1.rawData[5] * this.matrix[9] + _loc_1.rawData[6] * this.matrix[14] + _loc_1.rawData[7] * this.matrix[15]);
            this.matrix[10] = _loc_1.rawData[8];
            this.matrix[11] = _loc_1.rawData[9];
            this.matrix[12] = _loc_1.rawData[10];
            this.matrix[13] = _loc_1.rawData[11];
            var _loc_5:* = -(_loc_1.rawData[8] * this.matrix[4] + _loc_1.rawData[9] * this.matrix[9] + _loc_1.rawData[10] * this.matrix[14] + _loc_1.rawData[11] * this.matrix[15]);
            this.matrix[15] = _loc_1.rawData[12];
            this.matrix[16] = _loc_1.rawData[13];
            this.matrix[17] = _loc_1.rawData[14];
            this.matrix[18] = _loc_1.rawData[15];
            var _loc_6:* = -(_loc_1.rawData[12] * this.matrix[4] + _loc_1.rawData[13] * this.matrix[9] + _loc_1.rawData[14] * this.matrix[14] + _loc_1.rawData[15] * this.matrix[15]);
            this.matrix[4] = _loc_3;
            this.matrix[9] = _loc_4;
            this.matrix[14] = _loc_5;
            this.matrix[19] = _loc_6;
            return true;
        }// end function

        public function applyMatrix(core.image:ColorMatrix/toGreyscale:uint) : uint
        {
            var _loc_2:* = core.image:ColorMatrix/toGreyscale >>> 24 & 255;
            var _loc_3:* = core.image:ColorMatrix/toGreyscale >>> 16 & 255;
            var _loc_4:* = core.image:ColorMatrix/toGreyscale >>> 8 & 255;
            var _loc_5:* = core.image:ColorMatrix/toGreyscale & 255;
            var _loc_6:* = 0.5 + _loc_3 * this.matrix[0] + _loc_4 * this.matrix[1] + _loc_5 * this.matrix[2] + _loc_2 * this.matrix[3] + this.matrix[4];
            var _loc_7:* = 0.5 + _loc_3 * this.matrix[5] + _loc_4 * this.matrix[6] + _loc_5 * this.matrix[7] + _loc_2 * this.matrix[8] + this.matrix[9];
            var _loc_8:* = 0.5 + _loc_3 * this.matrix[10] + _loc_4 * this.matrix[11] + _loc_5 * this.matrix[12] + _loc_2 * this.matrix[13] + this.matrix[14];
            var _loc_9:* = 0.5 + _loc_3 * this.matrix[15] + _loc_4 * this.matrix[16] + _loc_5 * this.matrix[17] + _loc_2 * this.matrix[18] + this.matrix[19];
            if (_loc_9 < 0)
            {
                _loc_9 = 0;
            }
            if (_loc_9 > 255)
            {
                _loc_9 = 255;
            }
            if (_loc_6 < 0)
            {
                _loc_6 = 0;
            }
            if (_loc_6 > 255)
            {
                _loc_6 = 255;
            }
            if (_loc_7 < 0)
            {
                _loc_7 = 0;
            }
            if (_loc_7 > 255)
            {
                _loc_7 = 255;
            }
            if (_loc_8 < 0)
            {
                _loc_8 = 0;
            }
            if (_loc_8 > 255)
            {
                _loc_8 = 255;
            }
            return _loc_9 << 24 | _loc_6 << 16 | _loc_7 << 8 | _loc_8;
        }// end function

        public function transformVector(Math:Array) : void
        {
            if (Math.length != 4)
            {
                return;
            }
            var _loc_2:* = Math[0] * this.matrix[0] + Math[1] * this.matrix[1] + Math[2] * this.matrix[2] + Math[3] * this.matrix[3] + this.matrix[4];
            var _loc_3:* = Math[0] * this.matrix[5] + Math[1] * this.matrix[6] + Math[2] * this.matrix[7] + Math[3] * this.matrix[8] + this.matrix[9];
            var _loc_4:* = Math[0] * this.matrix[10] + Math[1] * this.matrix[11] + Math[2] * this.matrix[12] + Math[3] * this.matrix[13] + this.matrix[14];
            var _loc_5:* = Math[0] * this.matrix[15] + Math[1] * this.matrix[16] + Math[2] * this.matrix[17] + Math[3] * this.matrix[18] + this.matrix[19];
            Math[0] = _loc_2;
            Math[1] = _loc_3;
            Math[2] = _loc_4;
            Math[3] = _loc_5;
            return;
        }// end function

        private function initHue() : void
        {
            var _loc_2:Array = null;
            var _loc_3:Number = NaN;
            var _loc_4:Number = NaN;
            var _loc_1:Number = 39.1827;
            if (!this.hueInitialized)
            {
                this.hueInitialized = true;
                this.preHue = new ColorMatrix();
                this.preHue.rotateRed(45);
                this.preHue.rotateGreen(-_loc_1);
                _loc_2 = [LUMA_R2, LUMA_G2, LUMA_B2, 1];
                this.preHue.transformVector(_loc_2);
                _loc_3 = _loc_2[0] / _loc_2[2];
                _loc_4 = _loc_2[1] / _loc_2[2];
                this.preHue.shearBlue(_loc_3, _loc_4);
                this.postHue = new ColorMatrix();
                this.postHue.shearBlue(-_loc_3, -_loc_4);
                this.postHue.rotateGreen(_loc_1);
                this.postHue.rotateRed(-45);
            }
            return;
        }// end function

        private function rotateColor(Math:Number, Math:int, Math:int) : void
        {
            Math = Math * RAD;
            var _loc_4:* = IDENTITY.concat();
            var _loc_5:* = Math.cos(Math);
            _loc_4[Math + Math * 5] = Math.cos(Math);
            _loc_4[Math + Math * 5] = _loc_5;
            _loc_4[Math + Math * 5] = Math.sin(Math);
            _loc_4[Math + Math * 5] = -Math.sin(Math);
            this.concat(_loc_4);
            return;
        }// end function

        private function shearColor(Math:int, Math:int, Math:Number, Math:int, Math:Number) : void
        {
            var _loc_6:* = IDENTITY.concat();
            _loc_6[Math + Math * 5] = Math;
            _loc_6[Math + Math * 5] = Math;
            this.concat(_loc_6);
            return;
        }// end function

        public function toString() : String
        {
            return this.matrix.toString();
        }// end function

    }
}
